Coffee School Game Lesson Three - Using Game States

Code Editor

// Creating environment variables var playerSize = 10; var sceneWidth = 300, sceneHeight = 150; var groundHeight = 10; var playAreaHeight = (sceneHeight - groundHeight); // Create the variables to track player movement var playerVel = 0; // Stores the player's velocity var g = 0.4; // The constant acceleration cause by "gravity" // Object width! var objectWidth = 2 * playerSize; // Obstacle Counter var obstacleCounter = 0; // Sets the background colour Crafty.background("#ADD8E6"); Crafty.defineScene("Start", function() { // Introductory text Crafty.e("2D, DOM, Text") .attr({x: sceneWidth/2, y: sceneHeight/2, w: 100, h: 20}) .text("Press 'space' to begin") .css({"text-align":"center"}) // "Dummy" player Crafty.e("2D, DOM, Color") .attr({x: 30,y: 30, w: playerSize, h: playerSize}) .color("#ff0000") // Handle any keypress events .bind("KeyDown", function(event) { // If the key pressed is the space bar then move to the "Game" scene if(event.key == Crafty.keys.SPACE) { Crafty.enterScene("Game"); } }); // Dummy ground Crafty.e("2D, DOM, Color") .attr({x: 0, y: playAreaHeight, w: sceneWidth, h: groundHeight}) .color("#00ff00"); }); // Enter the start scene Crafty.enterScene("Start"); Crafty.defineScene("Game", function() { // Create the ground! Crafty.e("Solid, 2D, DOM, Color") .attr({x: 0, y: playAreaHeight, w: sceneWidth, h: groundHeight}) .color("#00ff00"); // Create our player's base entity Crafty.e("Collision, 2D, DOM, Color") // Specifying the components to add .attr({x: 30, y: 30, w: playerSize, h: playerSize}) // Specifying the dimensions and the point to draw from .checkHits("Solid") .color("#ff0000") // Specifying the colour of the rectangle .bind("EnterFrame", function() { // Binds the "EnterFrame" event to the entity if(this.y < 0) { playerVel = g; // Prevent the player from going above the game screen } else { playerVel += g; // Adds the "gravitational acceleration" to the player's velocity } this.y += playerVel; // Change the player entities y position based on the player velocity }) .bind("KeyDown", function(event) { // Binds the "KeyDown" event to our player entity if(event.key == Crafty.keys.SPACE){ // If the key is the spacebar then "flap" playerVel = -5; // Sets the player's speed and direction to go upwards } }) .bind("HitOn", function() { Crafty.pause(); }) .bind("EnterFrame", function() { Crafty("Obstacle").each(function() { if(this.x < -objectWidth) { this.destroy(); } else { this.x -= 3; } }); if(obstacleCounter > 100){ obstacleCounter = 0; newObstacle(); } obstacleCounter++; }); }); function newObstacle() { var randomHeight = Math.floor((Math.random() * (sceneHeight/2)) + (sceneHeight/3)); var bottomOfTopHalf = playAreaHeight - randomHeight; var topOfBottomHalf = bottomOfTopHalf + (4 * playerSize); // Create the top half of the pipe Crafty.e("Obstacle, 2D, DOM, Color, Solid") .attr({x: sceneWidth, y: 0, w: objectWidth, h: bottomOfTopHalf}) .color("#003319"); // Create the bottom half of the pipe Crafty.e("Obstacle, 2D, DOM, Color, Solid") .attr({x: sceneWidth, y: topOfBottomHalf, w: objectWidth, h: playAreaHeight - topOfBottomHalf}) .color("#003319"); }

Preview

Console Log:

Game Lesson Three - Using Game States

Part 2: Creating the Game Over Screen and Keeping Score

Goal: Creating the game over scene and displaying text in it.

Now that we have a start screen for our game we can create a game over screen for when the player loses the game. The game over screen can be used to show the player some text, in our case showing what score they managed to obtain before losing.

To create our game over screen we’re going to use a Crafty Scene again. Let’s place it between our Crafty.enterScene command for the Start Screen and the Crafty.defineScene command for the “Game” scene, using the same code that was used to define the other scenes:

Crafty.defineScene("GameOver", function(){
    // Game over screen stuff goes here
});

In the Game Over screen we can show some text to the player to tell them that they’ve lost, as well as drawing the ground to make the game over screen look a bit nicer.

To draw the text we can create a Crafty entity with the text component just like we did in the start screen.

Crafty.e("2D, DOM, Text")
  .attr({x: sceneWidth/2, y: sceneHeight/2, w: 100, h: 20})
  .text("Game Over!")
  .textFont({size: '14px', weight: 'bold'});

This text should go inside the “Game Over” scene we just made! Once the text is inside we can add the ground visual like we did in the start screen:

Crafty.e("2D, DOM, Color")
  .attr({x: 0, y: playAreaHeight, w: sceneWidth, h: groundHeight})
  .color("#00ff00");

Now that we have a game over screen we can change what happens in our “Game” scene when the player collides with an obstacle! We no longer need to use Crafty.pause on a collision because we now have the game over screen to change to.

All we need to do is swap out the Crafty.pause(); statement in the “HitOn” bind with the following scene change:

Crafty.enterScene("GameOver");

Now that we have a game over scene to switch to, we can keep score and show it on the game over which is what we’ll be doing next!